#ifndef FUNC_DEF_H
#define FUNC_DEF_H

#include"Fifo.h"
#include"types.h"
#include "SetupVar.h"

#define ISDIGIT(ch) ( (ch < 48) ? 0 : ( ( ch > 57 ) ? 0 : 1 ) )
#define TODIGIT(ch) (ch - 48)

#define MAX_SIZE 10

#define AccelerationSlope 1

#define STEPPinX  1
#define DIRPinX   2
#define STEPPinY  3
#define DIRPinY   4
#define STEPPinZ  5
#define DIRPinZ   6
#define STEPPinA  7
#define DIRPinA   8
#define STEPPinB  9
#define DIRPinB   10
#define STEPPinC  11
#define DIRPinC	  12

#define Spindle1 13
#define SpindleSpeedPin 14
#define Spindle2 15

#define FloodPin 16
#define MistPin 17

#define VdrivePinCLK 32
#define VdrivePinCS 30
#define VdrivePinDI 34
#define VdrivePinD0 36

// pin configuration to be assigned 
extern int pinCLK;    //arbitrary values
extern int pinCS;
extern int pinDI;
extern int pinDO;

/*enviornment variables*/
extern CANON_UNITS currUnit;
extern CANON_FEED_REFERENCE curreFeedRef;
extern CANON_PLANE currPlane;
extern CANON_MOTION_MODE currMotionMode;
extern CANON_DIRECTION direction;
extern CANON_SPEED_FEED_MODE currSpeedFeedMode;
extern CANON_PT Origin_X,Origin_Y,Origin_Z,Origin_A,Origin_B,Origin_C;
extern CANON_PT Cur_X,Cur_Y,Cur_Z,Cur_A,Cur_B,Cur_C;

extern char ackChar;

/**
 * @brief This method assigns the length units 
 *
 * @param units Current measurement unit i.e. inch, millimeter or centimeter 
 */
void USE_LENGTH_UNITS(CANON_UNITS units);

/**
 * @brief This method assigns the current plane
 *
 * @param plane Current plane i.e. CANON_PLANE_XY, CANON_PLANE_YZ, or CANON_PLANE_XZ
 */
void SELECT_PLANE(CANON_PLANE plane);

/**
 * @brief This method assigns the feed reference value
 *
 * @param reference Feed reference value i.e. CANON_XYZ, CANON_WORKPIECE
 */
void SET_FEED_REFERENCE(CANON_FEED_REFERENCE reference);

/**
 * @brief This method assigns the motion control mode
 *
 * @param mode Current motion control mode i.e. CANON_EXACT_STOP, CANON_EXACT_PATH, or CANON_CONTINUOUS
 */
void SET_MOTION_CONTROL_MODE(CANON_MOTION_MODE mode);

/**
 * @brief This method sets the origin offsets i.e. the origin at the point with absolute coordinates x, y, z, a, b, and c
 *
 * @param x X axis offset
 * @param y Y axis offset
 * @param z Z axis offset
 * @param a A axis offset
 * @param b B axis offset
 * @param c C axis offset
 */
void SET_ORIGIN_OFFSETS(CANON_PT x, CANON_PT y, CANON_PT z, CANON_PT a, CANON_PT b, CANON_PT c);

/**
 * @brief Method for straight traversal of the machining centre from initial to final point following an interpolated path at maximum feed rate. Linear interpolation is done by bressenham algorithm from initial(current) point to final point. It should be noted that no cutting takes place during STRAIGHT_TRAVERSAL.
 *
 * @param x Final X coordinate 
 * @param y Final Y coordinate
 * @param z Final Z coordinate
 * @param a Final A coordinate
 * @param b Final B coordinate
 * @param c Final C coordinate
 */
void STRAIGHT_TRAVERSE(CANON_PT x, CANON_PT y, CANON_PT z, CANON_PT a, CANON_PT b, CANON_PT c);


/**
 * @brief This method sets the feed rate at which the machining centre will move
 *
 * @param rate Feed rate value
 */
void SET_FEED_RATE(int rate);


/**
 * @brief This method begins exact synchronization of spindle with feed motion of the machining centre
 */
void START_SPEED_FEED_SYNCH();

/**
 * @brief This method stops exact synchronization of spindle with feed motion of the machining centre
 */
void STOP_SPEED_FEED_SYNCH();

/**
 * @brief This method moves the machining centre in a helical arc from the current position at the existing feed rate. The axis of the helix is parallel to the X, Y, or Z-axis, according to which one is perpendicular to the selected plane. The helical arc may degenerate to a circular arc if there is no motion parallel to the axis of the helix.
 *
 * @param first_end First coordinate of the selected plane of the end of the arc 
 * @param second_end Second coordinate of the selected plane of the end of the arc 
 * @param first_axis First coordinate of the selected plane of the axis of the arc 
 * @param second_axis Second coordinate of the selected plane of the axis of the arc 
 * @param rotation Decides whether the arc is traversed clockwise, counterclockwise or no rotation
 * @param axis_end_point is the end point coordinate value of the plane perpendicular to the selected plane 
 * @param a 
 * @param b
 * @param c
 */
void ARC_FEED(CANON_PT first_end, CANON_PT second_end, CANON_PT first_axis, CANON_PT second_axis, CANON_PT rotation, CANON_PT axis_end_point, CANON_PT a, CANON_PT b, CANON_PT c);

/**
 * @brief This method keeps all the axes to dwell(unmoving) for a specific amount of time 
 *
 * @param milliseconds Milliseconds for which dwelling is done
 */
void DWELL(int milliseconds);

/**
 * @brief This method moves the controlled point from initial point to final point given by the parameters of the funtion at the feed rate. STRAIGHT_FEED is different from STRAIGHT_TRAVERSE in the way that cutting takes place during STRAIGHT_FEED.
 *
 * @param x Final X coordinate
 * @param y Final Y coordinate
 * @param z Final Z coordinate
 * @param a Final A coordinate
 * @param b Final B coordinate
 * @param c Final C coordinate
 */
void STRAIGHT_FEED(CANON_PT x, CANON_PT y, CANON_PT z, CANON_PT a, CANON_PT b, CANON_PT c);

/**
 * @brief This method performs a probing action which is placed in the spindle. 
 *
 * @param x X coordinate of the point at which probing is required
 * @param y Y coordinate of the point at which probing is required
 * @param z Z coordinate of the point at which probing is required
 * @param a A coordinate of the point at which probing is required
 * @param b B coordinate of the point at which probing is required
 * @param c C coordinate of the point at which probing is required
 */
void STRAIGHT_PROBE(CANON_PT x, CANON_PT y, CANON_PT z, CANON_PT a, CANON_PT b, CANON_PT c);

/**
 * @brief This method orients the spindle in the direction specified to the angle specified by orienattion in degrees
 *
 * @param orientation Angle at which spindle is oriented in degrees
 * @param direction Direction in which it is turned
 */
void ORIENT_SPINDLE(int orientation, CANON_DIRECTION direction);

/**
 * @brief This method sets the spindle speed
 *
 * @param r Spindle speed value
 */
void SET_SPINDLE_SPEED(CANON_SPINDLE_SPEED r);

/**
 * @brief This method sets the direction of rotation of the spindle as clockwise
 */
void START_SPINDLE_CLOCKWISE();

/**
 * @brief This method sets the direction of rotation of the spindle as counterclockwise
 */
void START_SPINDLE_COUNTERCLOCKWISE();

/**
 * @brief This method stops the spindle
 */
void STOP_SPINDLE_TURNING();


/**
 * @brief This method results in the tool currently in the spindle being returned to its slot, and the tool from the slot designated by slot being inserted in the spindle.
 *
 * @param slot Slot value from where the tool is selected(can be zero)
 */
void CHANGE_TOOL(int slot);

/**
 * @brief This method selects the tool in the current slot
 *
 * @param Slot value from where the tool is selected 
 */
void SELECT_TOOL(int i);


/**
 * @brief This method sets the tool length offset to the given length.
 *
 * @param offset Offset value
 */
void USE_TOOL_LENGTH_OFFSET(int offset);

/**
 * @brief This method prints the text passed in the parameter of the function if the function calls are being printed.
 *
 * @param s Text to be printed
 */
void COMMENT(char * s);

/**
 * @brief This method overrides the function of the feed override switch. The feed rate takes its programmed value immediately.
 */
void DISABLE_FEED_OVERRIDE();

/**
 * @brief This method overrides the function of the speed override switch. The spindle speed takes its programmed value immediately.
 */
void DISABLE_SPEED_OVERRIDE();

/**
 * @brief This method enables the function of the feed override switch. The feed rate is selected from the switch settings.
 */
void ENABLE_FEED_OVERRIDE();

/**
 * @brief This method enables the function of the speed override switch. The spindle speed is selected from the switch settings.
 */
void ENABLE_SPEED_OVERRIDE();

/**
 * @brief This method turns the flood coolant off.
 */
void FLOOD_OFF();

/**
 * @brief This method turns the flood coolant on.
 */
void FLOOD_ON();


/**
 * @brief This method initializes the canonical output funtion 
 */
void INIT_CANON();


/**
 * @brief This method prints message on the display (if any) when called by another method. 
 *
 * @param s Text to be printed.
 */
void MESSAGE(char * s);


/**
 * @brief This method turns the mist coolant off.
 */
void MIST_OFF();

/**
 * @brief This method turns the mist coolant on.
 */
void MIST_ON();

/**
 * @brief
 */
void TURN_PROBE_ON();//not impelmented

/**
 * @brief 
 */
void TURN_PROBE_OFF();//not implemeted

/**
 * @brief This method linearly interpolates the path between initial and final point. The two points are passed as arguments to the method. Initial point is usually the current point.
 *
 * @param CANON_PT X coordinate of the initial point
 * @param CANON_PT Y coordinate of the initial point
 * @param CANON_PT Z coordinate of the initial point
 * @param CANON_PT A coordinate of the initial point
 * @param CANON_PT B coordinate of the initial point
 * @param CANON_PT C coordinate of the initial point
 * @param CANON_PT X coordinate of the final point
 * @param CANON_PT Y coordinate of the final point
 * @param CANON_PT Z coordinate of the final point
 * @param CANON_PT A coordinate of the final point
 * @param CANON_PT B coordinate of the final point
 * @param CANON_PT C coordinate of the final point
 */
void bressenheim(CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT);

/**
 * @brief This method linearly interpolates the path between initial and final point for compensating the backlash present in the machine.
 *
 * @param CANON_PT X coordinate of the initial point
 * @param CANON_PT Y coordinate of the initial point
 * @param CANON_PT Z coordinate of the initial point
 * @param CANON_PT A coordinate of the initial point
 * @param CANON_PT B coordinate of the initial point
 * @param CANON_PT C coordinate of the initial point
 * @param CANON_PT X coordinate of the final point
 * @param CANON_PT Y coordinate of the final point
 * @param CANON_PT Z coordinate of the final point
 * @param CANON_PT A coordinate of the final point
 * @param CANON_PT B coordinate of the final point
 * @param CANON_PT C coordinate of the final point
 */
void bressenheim_backlash_drive(CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT,CANON_PT);

/**
 * @brief This method calculates and returns the power of 10. The exponent value is passed in the argument.
 *
 * @param x Exponent value
 *
 * @return 10^x
 */
int32 power10(int x);

/**
 * @brief T
 *
 * @param int 
 * @param double
 *
 * @return 
 */
int SpeedProfile(int ,double); // Not implemented

/**
 * @brief This method compensates the backlash distance by adding it to the total distance which is required to be moved
 */
void ADD_BACKLASH();

/**
 * @brief This method creates an acceleration curve for smooth motion of the machining axes
 *
 * @param AXIS_RATE Feed rate of the axis which has the maximum feed rate among the six axes
 * @param t Time instant at which speed is to be caluclated
 * @param p a constant value
 * @param td a constant value
 *
 * @return Speed at time instant t
 */
int Speed_Profile_Acceleration(int AXIS_RATE,double t,float p,float td);

/**
 * @brief This method creates a deceleration curve for smooth motion of the machining axes
 *
 * @param AXIS_RATE Feed rate of the axis which has the maximum feed rate among the six axes
 * @param t Time instant at which speed is to be caluclated
 * @param p a constant value
 * @param td a constant value
 *
 * @return Speed at time instant t
 */
int Speed_Profile_Deceleration(int AXIS_RATE,double t,float p,float td);

/**
 * @brief This method calculates the square root of the number passed in the argument
 *
 * @param int64 Argument value
 *
 * @return Square root value
 */
int32 SquareRoot(int64);

/****/
//function to implement feed sync 


/**
 * @brief function to start the timer to implement speed feed synch, function used in implementation of SPEED_FEED_SYCH (implementation not tested)
 */
void start_sync_timer();

/**
 * @brief function to handle overflow situation of a timer while implementing speed feed sych, function used in implementation of SPEED_FEED_SYCH  (implementation not tested)
 */
void handler_overflow();

/**
 * @brief function to stop the timer to stop speed feed synch, function used in implementation of SPEED_FEED_SYCH (implementation not tested)
 */
void stop_sync_timer();

/**
 * @brief interrupt handler function while implementing SPEED_FEED_SYNCH (implementation not tested)
 */
void handler_spindle_interrupt();

#endif
